import fs from 'fs';
import path from 'path';
import { exec } from 'child_process';
import { promisify } from 'util';
import os from 'os';

const execAsync = promisify(exec);

/**
 * 备份管理器
 * 负责代理设置的备份和恢复
 */
export class BackupManager {
  constructor() {
    this.platform = os.platform();
    this.backupFile = path.join(process.cwd(), '.proxy-backup.json');
    this.originalProxySettings = null;
    this.COMMAND_TIMEOUT = 10000; // 10秒
  }

  /**
   * 备份当前代理设置
   */
  async backupCurrentSettings() {
    try {
      console.log('📋 备份当前代理设置...');
      
      if (this.platform === 'win32') {
        await this.backupWindowsSettings();
      } else if (this.platform === 'darwin') {
        await this.backupMacOSSettings();
      } else {
        throw new Error('不支持的操作系统');
      }
      
      // 保存到文件
      if (this.originalProxySettings) {
        await this.saveBackupToFile(this.originalProxySettings);
        console.log('📋 代理设置已备份到文件');
      }
      
    } catch (error) {
      console.error('❌ 备份代理设置失败:', error.message);
      throw error;
    }
  }

  /**
   * 备份Windows代理设置
   */
  async backupWindowsSettings() {
    try {
      const queryCommands = [
        'reg query "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyEnable',
        'reg query "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyServer',
        'reg query "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyOverride'
      ];

      const results = await Promise.all(
        queryCommands.map(cmd => this.executeWithTimeout(cmd).catch(err => ''))
      );

      // 解析注册表值
      const proxyEnable = this.parseRegValue(results[0], 'ProxyEnable');
      const proxyServer = this.parseRegValue(results[1], 'ProxyServer');
      const proxyOverride = this.parseRegValue(results[2], 'ProxyOverride');

      this.originalProxySettings = {
        platform: 'win32',
        proxyEnable: proxyEnable || 0,
        proxyServer: proxyServer || '',
        proxyOverride: proxyOverride || 'localhost;localhost:*;127.*;127.0.0.1:*;*.localhost;::1;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;192.168.*;<local>',
        timestamp: Date.now()
      };

      console.log('📋 已备份Windows代理设置:', this.originalProxySettings);

    } catch (error) {
      console.error('❌ 备份Windows代理设置失败:', error.message);
      throw error;
    }
  }

  /**
   * 备份macOS代理设置
   */
  async backupMacOSSettings() {
    try {
      // 获取网络服务列表
      const servicesOutput = await this.executeWithTimeout('networksetup -listallnetworkservices');
      const services = servicesOutput
        .split('\n')
        .slice(1) // 跳过第一行标题
        .map(line => line.trim())
        .filter(line => line && !line.startsWith('*'));

      const serviceSettings = {};

      // 备份每个网络服务的代理设置
      for (const service of services) {
        try {
          const webProxyOutput = await this.executeWithTimeout(`networksetup -getwebproxy "${service}"`);
          const httpsProxyOutput = await this.executeWithTimeout(`networksetup -getsecurewebproxy "${service}"`);

          serviceSettings[service] = {
            webProxy: this.parseMacOSProxyOutput(webProxyOutput),
            httpsProxy: this.parseMacOSProxyOutput(httpsProxyOutput)
          };
        } catch (error) {
          console.warn(`⚠️ 备份服务 ${service} 失败:`, error.message);
          serviceSettings[service] = null;
        }
      }

      this.originalProxySettings = {
        platform: 'darwin',
        services: serviceSettings,
        timestamp: Date.now()
      };

      console.log('📋 已备份macOS代理设置');

    } catch (error) {
      console.error('❌ 备份macOS代理设置失败:', error.message);
      throw error;
    }
  }

  /**
   * 从文件加载备份设置
   */
  async loadBackupFromFile() {
    try {
      if (fs.existsSync(this.backupFile)) {
        const backupData = JSON.parse(fs.readFileSync(this.backupFile, 'utf8'));
        this.originalProxySettings = backupData;
        console.log('📋 从文件加载备份设置:', backupData);
        return true;
      } else {
        console.log('⚠️ 备份文件不存在');
        return false;
      }
    } catch (error) {
      console.error('❌ 从文件加载备份设置失败:', error.message);
      return false;
    }
  }

  /**
   * 保存备份到文件
   */
  async saveBackupToFile(settings) {
    try {
      fs.writeFileSync(this.backupFile, JSON.stringify(settings, null, 2));
      console.log(`📋 备份已保存到: ${this.backupFile}`);
    } catch (error) {
      console.error('❌ 保存备份文件失败:', error.message);
      throw error;
    }
  }

  /**
   * 清理备份文件
   */
  cleanupBackupFile() {
    try {
      if (fs.existsSync(this.backupFile)) {
        fs.unlinkSync(this.backupFile);
        console.log('🗑️ 备份文件已清理');
      }
    } catch (error) {
      console.warn('⚠️ 清理备份文件失败:', error.message);
    }
  }

  /**
   * 同步从文件加载备份设置
   */
  loadBackupFromFileSync() {
    try {
      if (fs.existsSync(this.backupFile)) {
        const backupData = JSON.parse(fs.readFileSync(this.backupFile, 'utf8'));
        this.originalProxySettings = backupData;
        console.log('📋 同步从文件加载备份设置');
        return true;
      } else {
        console.log('⚠️ 备份文件不存在');
        return false;
      }
    } catch (error) {
      console.error('❌ 同步从文件加载备份设置失败:', error.message);
      return false;
    }
  }

  /**
   * 解析注册表值
   */
  parseRegValue(output, valueName) {
    if (!output) return null;
    
    const regMatch = output.match(new RegExp(`${valueName}\\s+REG_\\w+\\s+(.+)`));
    if (regMatch) {
      const value = regMatch[1].trim();
      // 如果是数字（DWORD），转换为整数
      if (/^(0x[0-9a-fA-F]+|\d+)$/.test(value)) {
        return parseInt(value);
      }
      return value;
    }
    return null;
  }

  /**
   * 解析macOS代理输出
   */
  parseMacOSProxyOutput(output) {
    const lines = output.split('\n');
    const info = {
      enabled: false,
      server: null,
      port: null
    };

    for (const line of lines) {
      if (line.includes('Enabled: Yes')) {
        info.enabled = true;
      } else if (line.includes('Server: ')) {
        info.server = line.split('Server: ')[1].trim();
      } else if (line.includes('Port: ')) {
        info.port = line.split('Port: ')[1].trim();
      }
    }

    return info;
  }

  /**
   * 获取备份状态
   */
  getBackupStatus() {
    return {
      hasBackup: !!this.originalProxySettings,
      backupFileExists: fs.existsSync(this.backupFile),
      backupFile: this.backupFile,
      platform: this.platform
    };
  }

  /**
   * 获取原始代理设置
   */
  getOriginalSettings() {
    return this.originalProxySettings;
  }

  /**
   * 设置原始代理设置
   */
  setOriginalSettings(settings) {
    this.originalProxySettings = settings;
  }

  /**
   * 执行命令（带超时）
   */
  async executeWithTimeout(command, timeout = this.COMMAND_TIMEOUT) {
    try {
      const { stdout } = await execAsync(command, {
        timeout,
        encoding: 'utf8'
      });
      return stdout.trim();
    } catch (error) {
      throw new Error(`命令执行失败: ${command} - ${error.message}`);
    }
  }
} 